/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.server.modules.sys.service.schedule;

import com.server.common.persistence.Page;
import com.server.common.service.CrudService;
import com.server.common.utils.StringUtils;
import com.server.modules.api.service.IMService;
import com.server.modules.sys.common.StaticDefine;
import com.server.modules.sys.dao.schedule.ScheduleDao;
import com.server.modules.sys.entity.User;
import com.server.modules.sys.entity.schedule.Schedule;
import com.server.modules.sys.entity.schedule.ScheduleUser;
import com.server.modules.sys.service.SystemService;
import com.server.modules.sys.utils.date.DateTimeUtil;
import com.server.modules.sys.vo.web.ScheduleViewAO;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日程Service
 * @author 丁光彪
 * @version 2016-12-23
 */
@Service
@Transactional(readOnly = true)
public class ScheduleService extends CrudService<ScheduleDao, Schedule> {
	@Resource
	private  ScheduleUserService scheduleUserService;
	@Resource
	private SystemService systemService;
    @Resource
    protected IMService imService;

	public Schedule get(String id) {
		return super.get(id);
	}
	
	public List<Schedule> findList(Schedule schedule) {
		return super.findList(schedule);
	}
	
	public Page<Schedule> findPage(Page<Schedule> page, Schedule schedule) {
		return super.findPage(page, schedule);
	}
	
	@Transactional(readOnly = false)
	public boolean saveNew(Schedule schedule,String scheduleUsersStr) {

		if(StringUtils.isEmpty(scheduleUsersStr)){
			return false;
		}
		//记录日程的重复规则数据
		if(schedule.getIsRepeat()){
			long interval=0;
			switch(schedule.getRepeatType()){
				case StaticDefine.DIC_REPEAT_TYPE.DAY:
					interval=Long.parseLong("86400")*schedule.getIntervalNum();
					break;
				case StaticDefine.DIC_REPEAT_TYPE.WEEK:
					interval=Long.parseLong("86400")*schedule.getIntervalNum()*7;
					break;
				case StaticDefine.DIC_REPEAT_TYPE.MONTH:
					interval=schedule.getIntervalNum();
					break;
				case StaticDefine.DIC_REPEAT_TYPE.YEAR:
					interval=schedule.getIntervalNum();
					break;
			}
			schedule.setIntervalNum(interval);
		}
		this.save(schedule);
		//保存参与人
		String scheduleId=schedule.getId();
		ScheduleUser au=new ScheduleUser();
		au.setUser(new User(scheduleUsersStr));
		au.setScheduleId(scheduleId);
		//创建人是参与人
		if(schedule.getCreateBy()!=null&&schedule.getCreateBy().getId().equals(scheduleUsersStr))		{
			au.setIsCreater(true);
		}else{
			//创建人
			ScheduleUser auCreate=new ScheduleUser();
			auCreate.setUser(schedule.getCreateBy());
			auCreate.setScheduleId(scheduleId);
			auCreate.setIsCreater(true);
			scheduleUserService.save(auCreate);
		}
		scheduleUserService.save(au);
		return true;
	}
	
	@Transactional(readOnly = false)
	public void delete(Schedule schedule) {
		super.delete(schedule);
	}

	/**
	 * 获取日程视图展示数据
	 * @param userId 用户标识
	 * @param startTime 显示开始时间
	 * @param endTime 显示结束时间
	 * @param type 类型-会议、事项
	 * @param viewType 日程显示类型-全部、我创建、别人创建
	 * @return 日程数据
	 */
	public List<ScheduleViewAO> getScheduleViewList(String userId, Date startTime, Date endTime, String type, String viewType) {
		List<Schedule> dataList =this.getScheduleList(userId,  startTime, endTime, type,viewType);

		List<ScheduleViewAO> retData = new ArrayList<>();

		if(!CollectionUtils.isEmpty(dataList)){
			for(Schedule data:dataList){
				ScheduleViewAO scheduleViewAO =new ScheduleViewAO();
				scheduleViewAO.setId(data.getId());
				scheduleViewAO.setTitle(data.getName());
				scheduleViewAO.setClassName("fc-pointer");
				scheduleViewAO.setAllDay(data.getIsAllDay());
				scheduleViewAO.setTrueAllDay(data.getIsAllDay());
				if(StaticDefine.DIC_SCHEDULE_TYPE.OTHER.equals(data.getType())){
					scheduleViewAO.setColor("#fff6cd");
					scheduleViewAO.setType("其他");
				}
				if(StaticDefine.DIC_SCHEDULE_TYPE.MATTER.equals(data.getType())){
					scheduleViewAO.setColor("#d4efff");
					scheduleViewAO.setType("事项");
				}
				if(data.getIsImportant()!=null&&data.getIsImportant()){
					scheduleViewAO.setTextColor("#fa4a4c");
				}else{
					scheduleViewAO.setTextColor("#333");
				}

				String start="";
				String end="";
				DateFormat format1 = new SimpleDateFormat("HH:mm");
				DateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
				DateFormat format3 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
				if(data.getOldEndDate()!=null&&data.getOldStartDate()!=null){
					String startTmp=format2.format(data.getStartTime());
					String endTmp=format2.format(data.getEndTime());
					start=startTmp+" "+format1.format(data.getOldStartDate());
					end=endTmp+" "+format1.format(data.getOldEndDate());
				}else{
					start=format3.format(data.getStartTime());
					end=format3.format(data.getEndTime());
				}
				long startTimeLong=data.getStartTime().getTime();
				long endTimeLong=data.getEndTime().getTime();

				if(endTimeLong-startTimeLong>=86400000){
					scheduleViewAO.setAllDay(true);
				}

				scheduleViewAO.setStart(start);
				scheduleViewAO.setEnd(end);
				retData.add(scheduleViewAO);
			}
		}

		return retData;
	}
	public List<Schedule> getScheduleList(String userId,Date startTime, Date endTime, String type,String viewType) {

		List<Schedule> scheduleList =new ArrayList<Schedule>();
		List<Schedule> noRepeatScheduleList;
		List<Schedule> repeatScheduleList;

		switch(viewType){
			case "ALL":
				//获取不重复日程列表
				noRepeatScheduleList=dao.getNoRepeatScheduleList(userId,  startTime, endTime, type);
				scheduleList.addAll(noRepeatScheduleList);
				break;
			case "MINE":
				//获取不重复日程列表
				noRepeatScheduleList=dao.getMyCreateScheduleList(userId,  startTime, endTime, type, false);
				scheduleList.addAll(noRepeatScheduleList);
				break;
			case "OTHERS":
				//获取不重复日程列表
				noRepeatScheduleList=dao.getOthersCreateScheduleList(userId,  startTime, endTime, type, false);
				scheduleList.addAll(noRepeatScheduleList);

				break;
		}

		//获取重复日程列表
		repeatScheduleList =this.getRepeatScheduleList(userId,  startTime, endTime, type,viewType);
		scheduleList.addAll(repeatScheduleList);

		return scheduleList;
	}
	/**
	 * 获取在显示范围内的重复日程
	 * @param userId 用户标识
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @param type 类型-会议、事项;传入为空则为全部
	 * @param viewType 日程显示类型
	 * @return 重复日程列表
	 */
	private List<Schedule> getRepeatScheduleList(String userId, Date startTime, Date endTime, String type,String viewType){
		List<Schedule> repeatScheduleList =new ArrayList<Schedule>();
		if("ALL".equals(viewType)){
			//先获取属于用户的且未结束重复的日程列表
			repeatScheduleList =dao.getRepeatScheduleList(userId,  startTime, endTime, type);
		}

		if("MINE".equals(viewType)){
			//先获取属于用户的且未结束重复的日程列表
			repeatScheduleList =dao.getMyCreateScheduleList(userId, startTime, endTime, type,true);
		}

		if("OTHERS".equals(viewType)){
			//先获取属于用户的且未结束重复的日程列表
			repeatScheduleList =dao.getOthersCreateScheduleList(userId, startTime, endTime, type,true);
		}

		List<Schedule> allScheduleList=new ArrayList<Schedule>();

		if(!CollectionUtils.isEmpty(repeatScheduleList)){
			for(Schedule schedule:repeatScheduleList){
				String repeatType=schedule.getRepeatType();
				switch(repeatType){
					//按照天重复
					case StaticDefine.DIC_REPEAT_TYPE.DAY:
						allScheduleList.addAll(getRepeatByDayScheduleList(schedule,startTime,endTime));
						break;
					//按照周重复
					case StaticDefine.DIC_REPEAT_TYPE.WEEK:
						allScheduleList.addAll(getRepeatByDayScheduleList(schedule,startTime,endTime));
						break;
					//按照月重复
					case StaticDefine.DIC_REPEAT_TYPE.MONTH:
						allScheduleList.addAll(getRepeatByMonthScheduleList(schedule,startTime,endTime));
						break;
					//按照年重复
					case StaticDefine.DIC_REPEAT_TYPE.YEAR:
						allScheduleList.addAll(getRepeatByYearScheduleList(schedule,startTime,endTime));
						break;
					default:

				}
			}
		}

		return allScheduleList;
	}
	/**
	 * 重复周期固定最小单位为天
	 * @param repeatSchedule 日程任务
	 * @param startTime 日程视图显示开始时间
	 * @param endTime 日程视图显示结束时间
	 * @return 重复任务列表
	 */
	private List<Schedule> getRepeatByDayScheduleList(Schedule repeatSchedule,Date startTime, Date endTime){

		List<Schedule> scheduleList=new ArrayList<Schedule>();

		Calendar cal = Calendar.getInstance();
		cal.setTime(endTime);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		Date endTimeTmp=cal.getTime();

		cal.clear();
		cal.setTime(startTime);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		Date startTimeTmp=cal.getTime();
		Date initStartTime=cal.getTime();


		Date scheduleRepeatEndTime=repeatSchedule.getRepeatEndTime();
		if(!repeatSchedule.getIsRepeatForever()){
			cal.clear();
			cal.setTime(scheduleRepeatEndTime);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			scheduleRepeatEndTime=cal.getTime();
		}

		cal.clear();
		cal.setTime(repeatSchedule.getStartTime());
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		long scheduleStartUnixTimestamp=cal.getTime().getTime();
		Date scheduleStartDate=cal.getTime();

		cal.clear();
		cal.setTime(repeatSchedule.getEndTime());
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		long scheduleEndUnixTimestamp=cal.getTime().getTime();

		long scheduleDuration=scheduleEndUnixTimestamp-scheduleStartUnixTimestamp;

		//任务的重复开始周期
		long interval=repeatSchedule.getIntervalNum()*1000;

		while(true){
			if(scheduleStartDate.after(startTimeTmp)){
				cal.clear();
				cal.setTime(startTimeTmp);
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.add(Calendar.DAY_OF_YEAR, 1);
				startTimeTmp=cal.getTime();
				if(startTimeTmp.after(endTimeTmp)){
					break;
				}else{
					continue;
				}
			}
			//任务的开始时间在今天
			long dayUnixTimestamp=startTimeTmp.getTime();
			long mod=(dayUnixTimestamp-scheduleStartUnixTimestamp)%interval;
			boolean canStart=true;
			if(!repeatSchedule.getIsRepeatForever()){
				//任务的重复结束日期小于当前日期
				if(scheduleRepeatEndTime.before(startTimeTmp)){
					canStart=false;
				}
			}
			if(mod==0&&canStart){
				Schedule newSchedule=new Schedule();
				//重新计算任务的开始时间和结束时间拷贝任务属性

				Date endTimeNew=new Date(dayUnixTimestamp+scheduleDuration);

				newSchedule.setId(repeatSchedule.getId());
				newSchedule.setName(repeatSchedule.getName());
				newSchedule.setStartTime(startTimeTmp);
				newSchedule.setEndTime(endTimeNew);
				newSchedule.setType(repeatSchedule.getType());
				newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
				newSchedule.setOldEndDate(repeatSchedule.getEndTime());
				newSchedule.setOldStartDate(repeatSchedule.getStartTime());
				newSchedule.setIsImportant(repeatSchedule.getIsImportant());


				scheduleList.add(newSchedule);
			}

			//任务的结束时间在今天,需要排除开始时间在本范围内的
			mod=(dayUnixTimestamp-scheduleEndUnixTimestamp)%interval;
			if(mod==0){
				//获取该任务的开始时间
				long tmpUnixTimestamp=dayUnixTimestamp-scheduleDuration;
				Date tmpDate=new java.util.Date(tmpUnixTimestamp);
				canStart=true;
				if(!repeatSchedule.getIsRepeatForever()){
					//任务的重复结束日期小于当前日期
					if(scheduleRepeatEndTime.before(tmpDate)){
						canStart=false;
					}
				}
				if(tmpDate.before(initStartTime)&&!tmpDate.before(scheduleStartDate)&&canStart){
					Schedule newSchedule=new Schedule();
					//重新计算任务的开始时间和结束时间拷贝任务属性

					newSchedule.setId(repeatSchedule.getId());
					newSchedule.setName(repeatSchedule.getName());
					newSchedule.setStartTime(tmpDate);
					newSchedule.setEndTime(startTimeTmp);
					newSchedule.setType(repeatSchedule.getType());
					newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
					newSchedule.setOldEndDate(repeatSchedule.getEndTime());
					newSchedule.setOldStartDate(repeatSchedule.getStartTime());
					newSchedule.setIsImportant(repeatSchedule.getIsImportant());

					scheduleList.add(newSchedule);
				}
			}

			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.add(Calendar.DAY_OF_YEAR, 1);

			startTimeTmp=cal.getTime();
			if(startTimeTmp.after(endTimeTmp)){
				break;
			}
		}
		//任务的开始时间和结束时间都不再范围内的
		long tmp2=endTimeTmp.getTime()-initStartTime.getTime();
		if(scheduleDuration>tmp2){
			cal.clear();
			cal.setTime(startTime);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.roll(Calendar.DAY_OF_YEAR, -1);
			startTimeTmp=cal.getTime();
			while(true){
				if(startTimeTmp.before(repeatSchedule.getStartTime())){
					break;
				}
				if(!repeatSchedule.getIsRepeatForever()){
					if(repeatSchedule.getRepeatEndTime().before(startTimeTmp)){
						break;
					}
				}

				long otherDuration=initStartTime.getTime()-startTimeTmp.getTime();
				if(otherDuration>scheduleDuration){
					break;
				}
				if(((startTimeTmp.getTime()-initStartTime.getTime())%interval)==0){
					long tmp=startTimeTmp.getTime()+scheduleDuration;
					if(tmp>endTimeTmp.getTime()){
						Schedule newSchedule=new Schedule();
						//重新计算任务的开始时间和结束时间拷贝任务属性
						newSchedule.setId(repeatSchedule.getId());
						newSchedule.setName(repeatSchedule.getName());
						newSchedule.setStartTime(startTimeTmp);
						newSchedule.setEndTime(new Date(tmp));
						newSchedule.setType(repeatSchedule.getType());
						newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
						newSchedule.setOldEndDate(repeatSchedule.getEndTime());
						newSchedule.setOldStartDate(repeatSchedule.getStartTime());
						newSchedule.setIsImportant(repeatSchedule.getIsImportant());

						scheduleList.add(newSchedule);
					}else{
						break;
					}
				}
				cal.clear();
				cal.setTime(startTimeTmp);
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.roll(Calendar.DAY_OF_YEAR, -1);
				startTimeTmp=cal.getTime();
			}
		}
		return scheduleList;
	}
	/**
	 * 按年重复
	 * @param repeatSchedule 日程任务
	 * @param startTime 显示开始时间
	 * @param endTime 显示结束时间
	 * @return 重复任务列表
	 */
	private List<Schedule> getRepeatByYearScheduleList(Schedule repeatSchedule,Date startTime, Date endTime){
		List<Schedule> scheduleList=new ArrayList<Schedule>();

		Calendar cal = Calendar.getInstance();
		cal.setTime(endTime);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		Date endTimeTmp=cal.getTime();

		cal.clear();
		cal.setTime(startTime);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		Date startTimeTmp=cal.getTime();
		Date initStartTime=cal.getTime();


		Date scheduleRepeatEndTime=repeatSchedule.getRepeatEndTime();
		if(!repeatSchedule.getIsRepeatForever()){
			cal.clear();
			cal.setTime(scheduleRepeatEndTime);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			scheduleRepeatEndTime=cal.getTime();
		}

		cal.clear();
		cal.setTime(repeatSchedule.getStartTime());
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		long scheduleStartUnixTimestamp=cal.getTime().getTime();
		Date scheduleStartDate=cal.getTime();
		int scheduleStartDayNum=cal.get(Calendar.DAY_OF_MONTH);
		int scheduleStartMonthNum=cal.get(Calendar.MONTH);
		int scheduleStartYearNum=cal.get(Calendar.YEAR);

		cal.clear();
		cal.setTime(repeatSchedule.getEndTime());
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		long scheduleEndUnixTimestamp=cal.getTime().getTime();
		long scheduleDuration=scheduleEndUnixTimestamp-scheduleStartUnixTimestamp;
		int scheduleDurationDayNum=(int)scheduleDuration/86400000;

		//任务的重复开始周期月份
		long interval=repeatSchedule.getIntervalNum();

		while(true){
			if(scheduleStartDate.after(startTimeTmp)){
				cal.clear();
				cal.setTime(startTimeTmp);
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.add(Calendar.DAY_OF_YEAR, 1);
				startTimeTmp=cal.getTime();
				if(startTimeTmp.after(endTimeTmp)){
					break;
				}else{
					continue;
				}
			}
			boolean canStart=true;
			if(!repeatSchedule.getIsRepeatForever()){
				//任务的重复结束日期大于当前日期
				if(scheduleRepeatEndTime.before(startTimeTmp)){
					canStart=false;
				}
			}
			//任务的开始时间在今天
			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			int dayNum=cal.get(Calendar.DAY_OF_MONTH);
			int monthNum=cal.get(Calendar.MONTH);
			int yearNum=cal.get(Calendar.YEAR);
			int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
			boolean isDayOk=false;
			if(monthNum==scheduleStartMonthNum){
				if(dayNum==scheduleStartDayNum){
					isDayOk=true;
				}else{
					if(dayNum==lastDay){
						if(dayNum<=scheduleStartDayNum){
							isDayOk=true;
						}
					}
				}
			}

			if(isDayOk&&canStart){
				int yearSpace=yearNum-scheduleStartYearNum;
				if(yearSpace>=0&&yearSpace%interval==0){
					Schedule newSchedule=new Schedule();
					//重新计算任务的开始时间和结束时间拷贝任务属性
					Date endTimeNew=new Date(startTimeTmp.getTime()+scheduleDuration);

					newSchedule.setId(repeatSchedule.getId());
					newSchedule.setName(repeatSchedule.getName());
					newSchedule.setStartTime(startTimeTmp);
					newSchedule.setEndTime(endTimeNew);
					newSchedule.setType(repeatSchedule.getType());
					newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
					newSchedule.setOldEndDate(repeatSchedule.getEndTime());
					newSchedule.setOldStartDate(repeatSchedule.getStartTime());
					newSchedule.setIsImportant(repeatSchedule.getIsImportant());

					scheduleList.add(newSchedule);
				}
			}

			//任务的结束时间在今天,需要排除开始时间在本范围内的
			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.add(Calendar.DAY_OF_YEAR, -scheduleDurationDayNum);
			Date otherStartTmp=cal.getTime();

			dayNum=cal.get(Calendar.DAY_OF_MONTH);
			monthNum=cal.get(Calendar.MONTH);
			yearNum=cal.get(Calendar.YEAR);
			lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
			isDayOk=false;
			if(monthNum==scheduleStartMonthNum){
				if(dayNum==scheduleStartDayNum){
					isDayOk=true;
				}else{
					if(dayNum==lastDay){
						if(dayNum<=scheduleStartDayNum){
							isDayOk=true;
						}
					}
				}
			}
			if(isDayOk){
				int yearSpace=yearNum-scheduleStartYearNum;
				if(yearSpace>=0&&yearSpace%interval==0){
					canStart=true;
					if(!repeatSchedule.getIsRepeatForever()){
						//任务的重复结束日期小于当前日期
						if(scheduleRepeatEndTime.before(otherStartTmp)){
							canStart=false;
						}
					}
					if(otherStartTmp.before(initStartTime)&&!otherStartTmp.before(scheduleStartDate)&&canStart){
						Schedule newSchedule=new Schedule();
						//重新计算任务的开始时间和结束时间拷贝任务属性

						newSchedule.setId(repeatSchedule.getId());
						newSchedule.setName(repeatSchedule.getName());
						newSchedule.setStartTime(otherStartTmp);
						newSchedule.setEndTime(startTimeTmp);
						newSchedule.setType(repeatSchedule.getType());
						newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
						newSchedule.setOldEndDate(repeatSchedule.getEndTime());
						newSchedule.setOldStartDate(repeatSchedule.getStartTime());
						newSchedule.setIsImportant(repeatSchedule.getIsImportant());

						scheduleList.add(newSchedule);
					}

				}
			}

			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.add(Calendar.DAY_OF_YEAR, 1);

			startTimeTmp=cal.getTime();
			if(startTimeTmp.after(endTimeTmp)){
				break;
			}
		}

		//任务的开始时间和结束时间都不再范围内的
		long tmp2=endTimeTmp.getTime()-initStartTime.getTime();
		if(scheduleDuration>tmp2){
			cal.clear();
			cal.setTime(startTime);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.roll(Calendar.DAY_OF_YEAR, -1);
			startTimeTmp=cal.getTime();
			while(true){
				if(startTimeTmp.before(repeatSchedule.getStartTime())){
					break;
				}
				if(!repeatSchedule.getIsRepeatForever()){
					if(repeatSchedule.getRepeatEndTime().before(startTimeTmp)){
						break;
					}
				}
				long otherDuration=initStartTime.getTime()-startTimeTmp.getTime();
				if(otherDuration>scheduleDuration){
					break;
				}

				int dayNum=cal.get(Calendar.DAY_OF_MONTH);
				int monthNum=cal.get(Calendar.MONTH);
				int yearNum=cal.get(Calendar.YEAR);
				int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
				boolean isDayOk=false;
				if(monthNum==scheduleStartMonthNum){
					if(dayNum==scheduleStartDayNum){
						isDayOk=true;
					}else{
						if(dayNum==lastDay){
							if(dayNum<=scheduleStartDayNum){
								isDayOk=true;
							}
						}
					}
				}
				if(isDayOk){
					int yearSpace=yearNum-scheduleStartYearNum;
					if(yearSpace>=0&&yearSpace%interval==0){
						cal.clear();
						cal.setTime(startTimeTmp);
						cal.set(Calendar.HOUR_OF_DAY, 0);
						cal.set(Calendar.MINUTE, 0);
						cal.set(Calendar.SECOND, 0);
						cal.roll(Calendar.DAY_OF_YEAR, scheduleDurationDayNum);
						Date otherEndTmp=cal.getTime();
						if(otherEndTmp.after(endTimeTmp)){
							Schedule newSchedule=new Schedule();
							//重新计算任务的开始时间和结束时间拷贝任务属性
							newSchedule.setId(repeatSchedule.getId());
							newSchedule.setName(repeatSchedule.getName());
							newSchedule.setStartTime(startTimeTmp);
							newSchedule.setEndTime(otherEndTmp);
							newSchedule.setType(repeatSchedule.getType());
							newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
							newSchedule.setOldEndDate(repeatSchedule.getEndTime());
							newSchedule.setOldStartDate(repeatSchedule.getStartTime());
							newSchedule.setIsImportant(repeatSchedule.getIsImportant());
							scheduleList.add(newSchedule);
						}else{
							break;
						}
					}
				}

				cal.clear();
				cal.setTime(startTimeTmp);
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.roll(Calendar.DAY_OF_YEAR, -1);
				startTimeTmp=cal.getTime();
			}
		}
		return scheduleList;
	}

	/**
	 * 按月重复
	 * @param repeatSchedule 日程任务
	 * @param startTime 显示开始时间
	 * @param endTime 显示结束时间
	 * @return 重复任务列表
	 */
	private List<Schedule> getRepeatByMonthScheduleList(Schedule repeatSchedule,Date startTime, Date endTime){
		List<Schedule> scheduleList=new ArrayList<Schedule>();

		Calendar cal = Calendar.getInstance();
		cal.setTime(endTime);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		Date endTimeTmp=cal.getTime();

		cal.clear();
		cal.setTime(startTime);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		Date startTimeTmp=cal.getTime();
		Date initStartTime=cal.getTime();


		Date scheduleRepeatEndTime=repeatSchedule.getRepeatEndTime();
		if(!repeatSchedule.getIsRepeatForever()){
			cal.clear();
			cal.setTime(scheduleRepeatEndTime);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			scheduleRepeatEndTime=cal.getTime();
		}

		cal.clear();
		cal.setTime(repeatSchedule.getStartTime());
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		long scheduleStartUnixTimestamp=cal.getTime().getTime();
		Date scheduleStartDate=cal.getTime();
		int scheduleStartDayNum=cal.get(Calendar.DAY_OF_MONTH);

		cal.clear();
		cal.setTime(repeatSchedule.getEndTime());
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		long scheduleEndUnixTimestamp=cal.getTime().getTime();
		long scheduleDuration=scheduleEndUnixTimestamp-scheduleStartUnixTimestamp;
		int scheduleDurationDayNum=(int)scheduleDuration/86400000;

		//任务的重复开始周期月份
		long interval=repeatSchedule.getIntervalNum();

		while(true){
			if(scheduleStartDate.after(startTimeTmp)){
				cal.clear();
				cal.setTime(startTimeTmp);
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.add(Calendar.DAY_OF_YEAR, 1);
				startTimeTmp=cal.getTime();
				if(startTimeTmp.after(endTimeTmp)){
					break;
				}else{
					continue;
				}
			}
			boolean canStart=true;
			if(!repeatSchedule.getIsRepeatForever()){
				//任务的重复结束日期大于当前日期
				if(scheduleRepeatEndTime.before(startTimeTmp)){
					canStart=false;
				}
			}

			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			//任务的开始时间在今天
			int dayNum=cal.get(Calendar.DAY_OF_MONTH);
			int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
			boolean isDayOk=false;
			if(dayNum==lastDay){
				if(dayNum<=scheduleStartDayNum){
					isDayOk=true;
				}
			}else{
				if(dayNum==scheduleStartDayNum){
					isDayOk=true;
				}
			}

			if(isDayOk&&canStart){
				int monthSpace= DateTimeUtil.getMonthSpace(scheduleStartDate, startTimeTmp);
				if(monthSpace>=0&&monthSpace%interval==0){
					Schedule newSchedule=new Schedule();
					//重新计算任务的开始时间和结束时间拷贝任务属性

					Date endTimeNew=new Date(startTimeTmp.getTime()+scheduleDuration);

					newSchedule.setId(repeatSchedule.getId());
					newSchedule.setName(repeatSchedule.getName());
					newSchedule.setStartTime(startTimeTmp);
					newSchedule.setEndTime(endTimeNew);
					newSchedule.setType(repeatSchedule.getType());
					newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
					newSchedule.setOldEndDate(repeatSchedule.getEndTime());
					newSchedule.setOldStartDate(repeatSchedule.getStartTime());
					newSchedule.setIsImportant(repeatSchedule.getIsImportant());

					scheduleList.add(newSchedule);
				}
			}

			//任务的结束时间在今天,需要排除开始时间在本范围内的
			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.add(Calendar.DAY_OF_YEAR, -scheduleDurationDayNum);
			Date otherStartTmp=cal.getTime();

			dayNum=cal.get(Calendar.DAY_OF_MONTH);
			lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
			isDayOk=false;
			if(dayNum==lastDay){
				if(dayNum<=scheduleStartDayNum){
					isDayOk=true;
				}
			}else{
				if(dayNum==scheduleStartDayNum){
					isDayOk=true;
				}
			}

			if(isDayOk){
				int monthSpace=DateTimeUtil.getMonthSpace(scheduleStartDate, otherStartTmp);
				if(monthSpace>=0&&monthSpace%interval==0){
					canStart=true;
					if(!repeatSchedule.getIsRepeatForever()){
						//任务的重复结束日期小于当前日期
						if(scheduleRepeatEndTime.before(otherStartTmp)){
							canStart=false;
						}
					}
					if(otherStartTmp.before(initStartTime)&&!otherStartTmp.before(scheduleStartDate)&&canStart){
						Schedule newSchedule=new Schedule();
						//重新计算任务的开始时间和结束时间拷贝任务属性

						newSchedule.setId(repeatSchedule.getId());
						newSchedule.setName(repeatSchedule.getName());
						newSchedule.setStartTime(otherStartTmp);
						newSchedule.setEndTime(otherStartTmp);
						newSchedule.setType(repeatSchedule.getType());
						newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
						newSchedule.setOldEndDate(repeatSchedule.getEndTime());
						newSchedule.setOldStartDate(repeatSchedule.getStartTime());
						newSchedule.setIsImportant(repeatSchedule.getIsImportant());

						scheduleList.add(newSchedule);
					}

				}
			}

			cal.clear();
			cal.setTime(startTimeTmp);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.add(Calendar.DAY_OF_YEAR, 1);

			startTimeTmp=cal.getTime();
			if(startTimeTmp.after(endTimeTmp)){
				break;
			}
		}

		//任务的开始时间和结束时间都不再范围内的
		long tmp2=endTimeTmp.getTime()-initStartTime.getTime();
		if(scheduleDuration>tmp2){
			cal.clear();
			cal.setTime(startTime);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.roll(Calendar.DAY_OF_YEAR, -1);
			startTimeTmp=cal.getTime();
			while(true){
				if(startTimeTmp.before(repeatSchedule.getStartTime())){
					break;
				}
				if(!repeatSchedule.getIsRepeatForever()){
					if(repeatSchedule.getRepeatEndTime().before(startTimeTmp)){
						break;
					}
				}
				long otherDuration=initStartTime.getTime()-startTimeTmp.getTime();
				if(otherDuration>scheduleDuration){
					break;
				}
				int dayNum=cal.get(Calendar.DAY_OF_MONTH);
				int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
				boolean isDayOk=false;
				if(dayNum==lastDay){
					if(dayNum<=scheduleStartDayNum){
						isDayOk=true;
					}
				}else{
					if(dayNum==scheduleStartDayNum){
						isDayOk=true;
					}
				}
				if(isDayOk){
					int monthSpace=DateTimeUtil.getMonthSpace(scheduleStartDate,startTimeTmp);
					if(monthSpace>=0&&monthSpace%interval==0){
						cal.clear();
						cal.setTime(startTimeTmp);
						cal.set(Calendar.HOUR_OF_DAY, 0);
						cal.set(Calendar.MINUTE, 0);
						cal.set(Calendar.SECOND, 0);
						cal.roll(Calendar.DAY_OF_YEAR, scheduleDurationDayNum);
						Date otherEndTmp=cal.getTime();
						if(otherEndTmp.after(endTimeTmp)){
							Schedule newSchedule=new Schedule();
							//重新计算任务的开始时间和结束时间拷贝任务属性

							newSchedule.setId(repeatSchedule.getId());
							newSchedule.setName(repeatSchedule.getName());
							newSchedule.setStartTime(startTimeTmp);
							newSchedule.setEndTime(otherEndTmp);
							newSchedule.setType(repeatSchedule.getType());
							newSchedule.setIsAllDay(repeatSchedule.getIsAllDay());
							newSchedule.setOldEndDate(repeatSchedule.getEndTime());
							newSchedule.setOldStartDate(repeatSchedule.getStartTime());
							newSchedule.setIsImportant(repeatSchedule.getIsImportant());

							scheduleList.add(newSchedule);
						}else{
							break;
						}
					}


				}

				cal.clear();
				cal.setTime(startTimeTmp);
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.roll(Calendar.DAY_OF_YEAR, -1);
				startTimeTmp=cal.getTime();
			}
		}
		return scheduleList;
	}
    @Transactional(readOnly = false)
	public boolean saveEdit(Schedule schedule, String scheduleUsersStr) {
		if(schedule==null||StringUtils.isEmpty(schedule.getId())){
			return false;
		}
		if(StringUtils.isEmpty(scheduleUsersStr)){
			return false;
		}
		//记录日程的重复规则数据
		if(schedule.getIsRepeat()){
			long interval=0;
			switch(schedule.getRepeatType()){
				case StaticDefine.DIC_REPEAT_TYPE.DAY:
					interval=Long.parseLong("86400")*schedule.getIntervalNum();
					break;
				case StaticDefine.DIC_REPEAT_TYPE.WEEK:
					interval=Long.parseLong("86400")*schedule.getIntervalNum()*7;
					break;
				case StaticDefine.DIC_REPEAT_TYPE.MONTH:
					interval=schedule.getIntervalNum();
					break;
				case StaticDefine.DIC_REPEAT_TYPE.YEAR:
					interval=schedule.getIntervalNum();
					break;
			}
			schedule.setIntervalNum(interval);
		}
		this.save(schedule);
		//删除之前的参与人
		ScheduleUser suu=new ScheduleUser();
		suu.setScheduleId(schedule.getId());
        List<ScheduleUser> list = scheduleUserService.findList(suu);
        for (ScheduleUser scheduleUser : list) {
            scheduleUserService.deleteTrue(scheduleUser);
        }

        //保存参与人
		String scheduleId=schedule.getId();
		ScheduleUser au=new ScheduleUser();
		au.setUser(new User(scheduleUsersStr));
		au.setScheduleId(scheduleId);
		//创建人是参与人
		if(schedule.getCreateBy()!=null&&schedule.getCreateBy().getId().equals(scheduleUsersStr))		{
			au.setIsCreater(true);
		}else{
			//创建人
			ScheduleUser auCreate=new ScheduleUser();
			auCreate.setUser(schedule.getCreateBy());
			auCreate.setScheduleId(scheduleId);
			auCreate.setIsCreater(true);
			scheduleUserService.save(auCreate);
		}
		scheduleUserService.save(au);
		return true;
	}

    public void remindInTimeSchedules() {
        Date currentDate=new Date();
        Date startTime=null;
        Date endTime=null;
        List<ScheduleViewAO> all = this.getScheduleViewList(null, currentDate, currentDate, null, "ALL");
        List<Schedule> allRemindSchedule=new ArrayList<>();
        System.out.println("定时任务....."+currentDate);
        System.out.println(all);
        for (ScheduleViewAO scheduleViewAO : all) {
            String id = scheduleViewAO.getId();
            Schedule schedule = this.get(new Schedule(id));
            ScheduleUser su=new ScheduleUser();
            su.setScheduleId(schedule.getId());
            List<ScheduleUser> list = scheduleUserService.findList(su);
            if(!CollectionUtils.isEmpty(list)){
                if(list.size()==1){
                    schedule.setScheduleUser(list.get(0));
                }else {
                    for (ScheduleUser scheduleUser : list) {
                        if(scheduleUser.getIsCreater()==null||!scheduleUser.getIsCreater()){
                            schedule.setScheduleUser(scheduleUser);
                            break;
                        }
                    }
                }
            }
            if(	!allRemindSchedule.contains(schedule)){
				allRemindSchedule.add(schedule);
			}
            }
        for (Schedule schedule : allRemindSchedule) {
            ScheduleUser scheduleUser = schedule.getScheduleUser();
            if(scheduleUser!=null&&scheduleUser.getUser()!=null){
                User user = scheduleUser.getUser();
                String id = user.getId();
                User user1 = systemService.getUser(id);
                if(user1!=null){
                    String msg="您好["+user.getName()+"]，您有待办事项["+schedule.getName()+"]待处理，请留意该事项并合理安排工作";
                  //  System.out.println(msg);
                    Map<String,String > msgMap = new HashedMap();
                    msgMap.put("type","text");
                    msgMap.put("msg",msg);
                    List<String> userList = new ArrayList<String>();
                    userList.add(user1.getHxUsername());
                    imService.sendSysMessages(userList,msgMap,null);
                }
            }

        }

    }
}